package com.std.getstuffdone;

/**
 * This class handles the Schedule Screen UI and controls
 * @author Team STD
 *
 */
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import models.DataSource;
import models.DbHelper;
import models.MyAdapter;
import models.Schedule;
import models.ScheduleMaker;
import models.Task;
import models.Utility;

import com.std.getstuffdone.R;

import android.app.AlertDialog;
import android.app.ListActivity;
import android.content.DialogInterface;
import android.content.Intent;
import android.os.Bundle;
import android.text.format.Time;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.AdapterView;
import android.widget.AdapterView.OnItemLongClickListener;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.ListView;

public class ScheduleScreenActivity extends ListActivity implements OnClickListener{
	// constant string values
    private final String STARTTIMELABEL = "Start Time: ";
    private final String DURATIONLABEL = "Duration: ";
    private final String PRIORITYLABEL = "Priority: ";
    
    private List<Task> tasksToDisplay;
    private Map<Integer, Integer> positionToResId;
    
    static  ArrayList<HashMap<String,String>> list; 
    
    private DataSource dataSource;
    
    private Collection<Task> scheduleList;
    private Collection<Task> regenerateTasks;
    
    // a request code for starting new activities
    int requestCode = 0;
    
    // this method is called every time the screen is resumed
    public void onResume() {
    	super.onResume();
    	displayScheduleTasks();
    }
	 	
    // this method is called every time the screen is created
	public void onCreate(Bundle savedInstanceState){
		super.onCreate(savedInstanceState);
		setContentView(R.layout.schedulescreenactivity);
		positionToResId = new HashMap<Integer, Integer>();
		
		dataSource = DataSource.getInstance(getApplicationContext());
        
		//setListAdapter(new ArrayAdapter<String>(this, R.layout.schedule_list_item, TASKS));
		Button regenerateButton = (Button)findViewById(R.id.regenerateButton);
		regenerateButton.setOnClickListener(this);
		
		// show all tasks scheduled
		displayScheduleTasks();
		
		// prepare list view
		ListView lv = getListView();
        lv.setTextFilterEnabled(true);
        	
		lv.setOnItemLongClickListener(new OnItemLongClickListener() {
		    public boolean onItemLongClick(AdapterView<?> parent, View clickedView,
		        int position, long id) {
		      
		    	long taskId = rowPositionToTaskId(position);
		    	ImageView subView = (ImageView)clickedView.findViewById(R.id.statusicon);
		    	if(positionToResId.containsKey(position)){
		    		subView.setImageResource(R.drawable.check32);
		    		positionToResId.remove(position);
		    		dataSource.open();
		    		dataSource.editScheduleTaskStatus(taskId, 0);
		    		dataSource.close();
		    		return true;
		    	} else {
		    		subView.setImageResource(R.drawable.check32green);
		    		positionToResId.put(position, 0);
		    		dataSource.open();
		    		dataSource.editScheduleTaskStatus(taskId, 1);
		    		dataSource.close();
		    		return true;
		    	}
		    }
		  });
	}
	
	// This method return the id of the task, whose information is displayed in given row
    private long rowPositionToTaskId(long rowPosition) {
            HashMap<String, String> taskInfo = list.get((int) rowPosition);
        String taskIdString = taskInfo.get("taskId");
        long taskId = Long.parseLong(taskIdString);
        return taskId;
    }
	
    // displays all tasks scheduled
	private void displayScheduleTasks() {
        // get tasks from database
        dataSource.open();
        List<Task> tasks = dataSource.getAllTasks(DbHelper.TABLE_SCHEDULE);
        dataSource.close();
                
        // populate planningList with all tasks from database
        tasksToDisplay = new ArrayList<Task>();
        for(int i = 0; i < tasks.size(); i++) {
            tasksToDisplay.add(tasks.get(i));
            if(tasks.get(i).isCompleted()) {
            	positionToResId.put(i, 0);
            }
        }
        
        // set the adapter information to display data
        list = new ArrayList<HashMap<String,String>>();
        populateList(tasksToDisplay);
        setListAdapter(new MyAdapter(this, list));
	}

	// populates list with data to display from a list of tasks
    // @param tasks A list of tasks to be displayed on screen
    private void populateList(List<Task> tasks) {
        for(Task t : tasks) {
                HashMap<String,String> temp = new HashMap<String,String>();
                temp.put("taskId", String.valueOf(t.getID()));
                temp.put("title", t.getTitle());
                temp.put("startTime", STARTTIMELABEL + parseTime(t.getStartTime()));
                temp.put("duration", DURATIONLABEL + t.getEstimatedDuration() + " min");
                temp.put("priority", PRIORITYLABEL + Utility.getPriorityString(t.getPriority()));
                temp.put("status", String.valueOf(t.isCompleted()));
                list.add(temp);
        }
    }
    
    //Clear all tasks is schedule screen
    private void clearAllScheduleTasks() {
    	dataSource.open();
    	dataSource.deleteAllTasks(DbHelper.TABLE_SCHEDULE);
    	dataSource.close();
    }
    // parses Time object to display in HH:MM string format
    // @param time Time object to display
    // @return String with time in HH:MM format. 'Time not set' if time is null
    private String parseTime(Time time) {
        if (time == null) {
                return "Not Set";
        }
        if(time.toString().substring(6,8).equals("13")) {
        	return time.toString().substring(9, 11) + ":" + time.toString().substring(11,13) + " [+1 Day]";
        }
        return time.toString().substring(9, 11) + ":" + time.toString().substring(11,13);
    }
	
    // switches between planning and schedule activities
    public void switchTabInActivity(int indexTabToSwitchTo){
    	TabWidget ParentActivity;
    	ParentActivity = (TabWidget) this.getParent();
    	ParentActivity.switchTab(indexTabToSwitchTo);
	}
    
	@Override
	// a menu is created when the menu button pressed
	public boolean onCreateOptionsMenu(Menu menu)
	{
		//creates a menu inflater
		MenuInflater inflater = getMenuInflater();
		//generates a Menu from a menu resource file
		//R.menu.main_menu represents the ID of the XML resource file
		inflater.inflate(R.menu.schedule_screen_menu, menu);
		return true;
	}
	 
  @Override
  public boolean onOptionsItemSelected(MenuItem item) {
          // Handle item selection
          switch (item.getItemId()) {
          case R.id.confirm_clear_schedule:
                  // clear all planning tasks
                  clearAllScheduleTasks();
                  displayScheduleTasks();
                  return true;
          case R.id.cancel_clear_schedule:
                  // cancel pressed, so do nothing
                  return true;
          case R.id.faq:
		      	 // TODO call faq activity
        	  Intent intent = new Intent(this, FAQActivity.class);
              startActivity(intent);
		      	 return true;
          default:
                  return super.onOptionsItemSelected(item);
          }
  }
	 
  	public void onClick(View v) {
		int viewId = v.getId();
		if(viewId == R.id.regenerateButton){
			//launch activity to set schedule start and end times
			launchStartEndTimeEntryActivity();
		}
	}

	private void launchStartEndTimeEntryActivity() {
		Intent newIntent = new Intent(this, StartEndTimeEntry.class);
    	startActivityForResult(newIntent, requestCode);
	}
	
	 @Override
     // This method handles the information received from EnterTaskInfo activity
     // on returning from EnterTaskInfo Activity
     protected void onActivityResult(int requestCode, int resultCode, Intent data){
             super.onActivityResult(requestCode, resultCode, data);
             if (resultCode == Utility.RETURN_CODE_START_END_TIME_INFO) {
             	
             	// start and end time for schedule returned
             	Bundle bundle = data.getExtras();
             	String startTimeString = bundle.getString(Utility.BUNDLE_TASK_START_TIME);
             	String endTimeString = bundle.getString(Utility.BUNDLE_TASK_END_TIME);
             	
             	String[] startTimeValues = startTimeString.split(":");
             	String[] endTimeValues = endTimeString.split(":");
             	
             	// time objects created for start and end time
             	Time startTime = new Time();
     			startTime.set(0, Integer.parseInt(startTimeValues[1]), Integer.parseInt(startTimeValues[0]), 0, 0, 0);

     			Time endTime = new Time();
     			endTime.set(0, Integer.parseInt(endTimeValues[1]), Integer.parseInt(endTimeValues[0]), 0, 0, 0);
     			
     			dataSource.open();
     			Collection<Task> completedTasks = dataSource.getAllCompletedTasks();
     			regenerateTasks = dataSource.getAllTasks(DbHelper.TABLE_REGENERATE);
     			dataSource.close();
     			for(Task t : completedTasks) {
     				regenerateTasks.remove(t);
     			}
     			Collection<Task> tasksToSchedule = new ArrayList<Task>();
     			for(Task t : regenerateTasks) {
     				Task copiedTask = new Task(t.getID(), t.getTitle(),t.getStartTime(), t.getEstimatedDuration(), t.getEstimatedTravel(), t.getPriority(), false);
     				tasksToSchedule.add(copiedTask);
     			}
     			try {
     				// get the schedule and get the collection of tasks from the schedule
     				Schedule s = ScheduleMaker.generateSchedule(tasksToSchedule, startTime, endTime);
         			scheduleList = s.getTasks();
         			dataSource.open();
         			dataSource.deleteAllTasks(DbHelper.TABLE_PREVIEW);
         			dataSource.savePreviewTasks(scheduleList);
         			dataSource.close();
         			if(scheduleList.size() == tasksToSchedule.size()) {
         				Utility.setAllTasksIncludedFlag(true);
         			}
         			else {
         				Utility.setAllTasksIncludedFlag(false);
         			}
         			Intent newIntent = new Intent(ScheduleScreenActivity.this, PreviewScheduleScreenActivity.class);
                    startActivityForResult(newIntent, requestCode);
     			}
     			catch(Exception e) {
     				AlertDialog.Builder builder = new AlertDialog.Builder(this);
     				builder.setTitle("Schedule Calculation Error");
     				builder.setMessage("Unexpected error occured. Please try again.");
     				builder.setInverseBackgroundForced(true);
     				builder.setPositiveButton("Ok", new DialogInterface.OnClickListener() {
							
							public void onClick(DialogInterface dialog, int which) {
								dialog.dismiss();
							}
						});
     				AlertDialog alert = builder.create();
     				alert.show();
     			}
             }
             else if (resultCode == Utility.RETURN_CODE_SAVE_PREVIEW) {
             	dataSource.open();
             	dataSource.deleteAllTasks(DbHelper.TABLE_REGENERATE);
             	dataSource.saveRegenerateTasks(regenerateTasks);
     			dataSource.deleteAllTasks(DbHelper.TABLE_SCHEDULE);
             	dataSource.saveScheduleTasks(scheduleList);
             	dataSource.close();
             }
             else {
                    // do nothing
             }
     }
}
